import type { VNode } from 'vue';

import { PageRequest, PageData, FilterGroup, FilterRule } from '#/request';
import { EnumSchema } from '#/common';
import { VxeTablePropTypes, VxeTableDefines, VxeGridPropTypes, VxeGridInstance } from 'vxe-table';
import type { ColEx } from '@/components/Form/src/types/index';
import { RenderCallbackParams, ComponentFormSchema } from '@/components/Form';
import type { FormProps } from '@/components/Form';
import { BasicTableProps, VxeColumnPropTypes } from '@/components/VxeTable';
import { FetchSetting } from '@/components/Table';
import { FormModeEnum } from '@/enums/formEnum';

import { FilterOperateEntity } from '@/enums/filterOperateEnum';

import { SearchFormPropsType } from './searchForm';
import { DetailFormProps } from './detailForm';

/** 查询参数 */
export interface FetchParams {
  /** 搜索信息 */
  searchInfo?: FilterGroup;
  /** 页 */
  page?: number;
  /** 排序信息 */
  sortInfo?: Recordable;
  /** 过滤信息 */
  filterInfo?: Recordable;
}

/** 表格配置 */
export interface TableProps extends BasicTableProps {
  /** 表格标题 */
  title?: string | ((data: Recordable) => string);
  /** 表格标题右侧提示信息 */
  helpMessage?: string | string[];
  /** 表格数据接口请求对象 */
  api?: (params: PageRequest) => Promise<PageData | any>;
  /** 额外的搜索参数 */
  searchInfo?: FilterGroup;
  /** 查询条件请求之前处理 */
  searchInfoFn?: (info: FilterGroup) => Promise<FilterGroup>;
  /** 请求之前处理参数 */
  beforeFetch?: Fn;
  /** 请求之后处理返回参数 */
  afterFetch?: Fn;
  /** 请求配置 */
  fetchSetting?: Partial<FetchSetting>;
  /** 立即请求 */
  immediate?: boolean;
  /** 在分页改变的时候清空选项 */
  clearSelectOnPageChange?: boolean;
  /** 列配置 */
  columns: AdColumn[];
  /** 是否显示序号列 */
  showSeqColumn?: boolean;
  /** 序号列规则 */
  seqColumnRule?: 'default' | 'page';
  /** 序号列配置 */
  seqColumnProps?: VxeTableDefines.ColumnOptions;
  /** 操作列配置 */
  actionColumn?: VxeTableDefines.ColumnOptions;
  /** 点击行是否选中 checkbox 或者 radio */
  clickToSelect?: boolean;
  /** 行选择类型 checkbox 或者 radio */
  selection?: 'checkbox' | 'radio' | null;
  /** 选择列配置 */
  selectColumnProps?: VxeTableDefines.ColumnOptions;
  /** 是否启用展开行 */
  expand?: boolean;
  /** 展开列配置 */
  expandColumnProps?: VxeTableDefines.ColumnOptions;
  /** 搜索表单 */
  searchForm: SearchFormPropsType;
  /** 自定义表单 */
  customForm: Partial<FormProps>;
  /** 详情表单 */
  detailForm?: DetailFormProps;
}

/** 表格列配置 */
export interface AdColumn<T = VxeTablePropTypes.Row> extends VxeTableDefines.ColumnOptions<T> {
  /** 是否必填 */
  required?: boolean;
  /** 是否允许搜索，根据这个值决定是否列在搜索列选择下拉列表中 */
  filterable?: boolean;
  /** 此列的过滤字段名(用于关联数据查询)
   * @description: 外键联表查询：比如对于 Blog 查询作者昵称，原 Index 为 'UserName'，此值需预设为 'User.UserName'，才能在后端正常查询到数据。
   * @description: 非外键联表查询：比如对于 Blog 查询作者昵称，原 Index 为 'UserName'，此值需预设为 'UserId'，然后配合设置 'filterJoin' 提交后端进行查询。
   */
  filterIndex?: string;
  /** 非外键关联查询，当需要非外键关联查询时，需要设置以配合关联实体查询。 */
  filterJoin?: {
    /** 非外键关联查询的实体类型*/
    entityType: string;
    /** 非外键关联查询的选择字段名 */
    filterField: string;
    /** 非外键关联查询的选择字段名，该字段在后端会自动射关联 'filterIndex'-->'dataIndex' 进行数据过滤。 */
    selectField: string;
  };
  /** 数据类型 */
  dataType?:
    | 'enum'
    | 'integer'
    | 'number'
    | 'quantity'
    | 'price'
    | 'amount'
    | 'rate'
    | 'percentage'
    | 'measure'
    | 'string'
    | 'text'
    | 'password'
    | 'email'
    | 'mobile'
    | 'url'
    | 'ipv4'
    | 'ipv6'
    | 'idcard'
    | 'guid'
    | 'boolean'
    | 'datetime'
    | 'date'
    | 'time'
    | 'array';
  /** 枚举数据 */
  enumData?: EnumSchema[];
  /** 表单是否显示，根据这个值决定是否在动态表单架构中显示 */
  formVisible?: boolean;
  /** 表单是否允许编辑，根据这个值决定是否在动态表单架构中可编辑 */
  formEditable?: boolean;
  /** 表单渲染配置项 */
  formRender?: VxeColumnPropTypes.EditRender<T>;
  /** 表单架构 */
  formSchema?: ComponentFormSchema;
  /** 表单自定义 */
  formCustomer?: {
    /** 列配置 */
    colProps?: Partial<ColEx>;
    /** 渲染呈现 */
    render?: (renderCallbackParams: RenderCallbackParams) => VNode | VNode[] | string;
  };
  /** 筛选操作实体集合 */
  entities?: FilterOperateEntity[];
}

/** 表格动作类型 */
export interface TableActionType {
  /** 获取表格对象 */
  getTable: () => VxeGridInstance | undefined;
  /** 打开详情表单 */
  openDetailForm: (formMode: FormModeEnum, record?: Recordable) => void;
  /** 重载表格数据 */
  reload: (opt?: FetchParams | undefined) => Promise<Recordable<any>[] | undefined>;
  /** 设置分页 */
  setPagination: (info: Partial<VxeGridPropTypes.PagerConfig>) => void;
  /** 设置加载状态 */
  setLoading: (loading: boolean) => void;
  /** 获取表格数据 */
  getData: <T = Recordable<any>>() => T[];
  /** 获取搜索信息 */
  getSearchInfo: <T = Recordable>() => T;
  /** 设置表格数据 */
  setData: <T = Recordable<any>>(values: T[]) => void;
  /** 设置表格属性 */
  setProps: (props: Partial<TableProps>) => void;
  /** 获取分页对象 */
  getPagination: () => VxeGridPropTypes.PagerConfig;
  /** 获取列 */
  getColumns: () => AdColumn[];
  /** 事件 */
  emit?: EmitType;
}

/**
 * 处理筛选条件组
 * @param g 处理前的筛选条件组
 * @param cols 高级表格列
 * @returns 处理后的筛选条件组
 */
export function handleFilterGroup(g: FilterGroup, cols: AdColumn[]) {
  if (!g.Operate) {
    return g;
  }
  const group = new FilterGroup();
  group.Operate = g.Operate;
  for (const item of g.Groups) {
    group.Groups.push(handleFilterGroup(item, cols));
  }
  for (const item of g.Rules) {
    let field = item.Field;
    const column = cols.find((m) => m.field === field);
    field = column?.filterIndex || field;
    const filterRule = new FilterRule(field, item.Value, item.Operate);
    filterRule.JoinEntityType = item.JoinEntityType || column?.filterJoin?.entityType;
    filterRule.JoinFilterField = item.JoinFilterField || column?.filterJoin?.filterField;
    filterRule.JoinSelectField = item.JoinSelectField || column?.filterJoin?.selectField;
    group.Rules.push(filterRule);
  }
  return group;
}
